package zip

import (
	"archive/zip"
	"gitee.com/injoyai/goutil/oss/file"
	"io"
	"io/ioutil"
	"os"
)

type Entity struct {
	Name string
	Data []*file.Data
}

func NewZip(name string) *Entity {
	return &Entity{
		Name: name,
	}
}

func (this *Entity) Add(f *os.File) *Entity {
	info, _ := f.Stat()
	bytes, _ := ioutil.ReadAll(f)
	this.Data = append(this.Data, file.NewData(info.Name(), bytes, info.IsDir()))
	return this
}

func (this *Entity) AddByte(name string, bytes []byte) *Entity {
	this.Data = append(this.Data, file.NewData(name, bytes))
	return this
}

func (this *Entity) AddStr(name, str string) *Entity {
	return this.AddByte(name, []byte(str))
}

func (this *Entity) AddDir(name string) *Entity {
	this.Data = append(this.Data, file.NewData(name, []byte{}, true))
	return this
}

func (this *Entity) Save() error {
	return NewZipData(this.Name, this.Data...)
}

func NewZipData(zipName string, data ...*file.Data) error {
	if err := file.NewPath(zipName).MkDir(); err != nil {
		return err
	}
	f, err := os.Create(zipName)
	if err != nil {
		return err
	}
	z := zip.NewWriter(f)
	defer z.Close()
	for _, v := range data {
		header := &zip.FileHeader{
			Name: v.Name(),
		}
		if v.IsDir() {
			header.Name += "/"
		}
		w, err := z.CreateHeader(header)
		if err != nil {
			return err
		}
		if _, err := io.Copy(w, v); err != nil {
			return err
		}
	}
	return nil
}

func NewZipFile(zipName string, files ...*os.File) error {
	if err := file.NewPath(zipName).MkDir(); err != nil {
		return err
	}
	f, err := os.Create(zipName)
	if err != nil {
		return err
	}
	z := zip.NewWriter(f)
	defer z.Close()
	for _, file := range files {
		defer file.Close()
		info, err := file.Stat()
		if err != nil {
			return err
		}
		header, err := zip.FileInfoHeader(info)
		if err != nil {
			return err
		}
		w, err := z.CreateHeader(header)
		if err != nil {
			return err
		}
		if _, err := io.Copy(w, file); err != nil {
			return err
		}
	}
	return nil
}
